{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# EXCEPTIONS AND ASSERTIONS\n",
    "\n",
    "An <b>“exception”</b>is usually defined as “something that does not conform to the norm,”\n",
    "\n",
    "They are everywhere in Python. . \n",
    "\n",
    "Virtually every module in the standard Python library uses them, \n",
    "\n",
    "and Python itself will <b>raise</b> them in many different circumstances。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test = [1,2,3]\n",
    "test[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>IndexError</b> is <b>the type of exception</b> that Python raises\n",
    "\n",
    "    when a program tries to access an element that is not within the bounds of an indexable type.\n",
    "\n",
    "The string following <b>IndexError</b>\n",
    "```\n",
    "list index out of range\n",
    "```\n",
    "provides <b>additional information</b> about what caused the exception to occur.\n",
    "```\n",
    " +-- LookupError\n",
    "      |    +-- IndexError\n",
    "      |    +-- KeyError\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=10 * (1/0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "4 + spam*3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'2' + 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Most of <b>the built-in exceptions</b> of Python deal with situations \n",
    "\n",
    "in which a program has attempted to execute a statement with no appropriate semantics。\n",
    "\n",
    "Among the most commonly occurring types of exceptions are\n",
    "\n",
    "```\n",
    "TypeError\n",
    "\n",
    "NameError\n",
    "\n",
    "ArithmeticError\n",
    "```\n",
    "\n",
    "### The Python Library Reference : \n",
    "\n",
    "CHAPTER FIVE  **BUILT-IN EXCEPTIONS**\n",
    "\n",
    "https://docs.python.org/3/library/exceptions.html\n",
    "#### 5.4. Exception hierarchy\n",
    "\n",
    "The class hierarchy for built-in exceptions is:\n",
    "\n",
    "```\n",
    "BaseException\n",
    " +-- SystemExit\n",
    " +-- KeyboardInterrupt\n",
    " +-- GeneratorExit\n",
    " +-- Exception\n",
    "      +-- StopIteration\n",
    "      +-- StopAsyncIteration\n",
    "      +-- ArithmeticError\n",
    "      |    +-- FloatingPointError\n",
    "      |    +-- OverflowError\n",
    "      |    +-- ZeroDivisionError\n",
    "      +-- AssertionError\n",
    "      +-- AttributeError\n",
    "      +-- BufferError\n",
    "      +-- EOFError\n",
    "      +-- ImportError\n",
    "      +-- LookupError\n",
    "      |    +-- IndexError\n",
    "      |    +-- KeyError\n",
    "      +-- MemoryError\n",
    "      +-- NameError\n",
    "      |    +-- UnboundLocalError\n",
    "      +-- OSError\n",
    "      |    +-- BlockingIOError\n",
    "      |    +-- ChildProcessError\n",
    "      |    +-- ConnectionError\n",
    "      |    |    +-- BrokenPipeError\n",
    "      |    |    +-- ConnectionAbortedError\n",
    "      |    |    +-- ConnectionRefusedError\n",
    "      |    |    +-- ConnectionResetError\n",
    "      |    +-- FileExistsError\n",
    "      |    +-- FileNotFoundError\n",
    "      |    +-- InterruptedError\n",
    "      |    +-- IsADirectoryError\n",
    "      |    +-- NotADirectoryError\n",
    "      |    +-- PermissionError\n",
    "      |    +-- ProcessLookupError\n",
    "      |    +-- TimeoutError\n",
    "      +-- ReferenceError\n",
    "      +-- RuntimeError\n",
    "      |    +-- NotImplementedError\n",
    "      |    +-- RecursionError\n",
    "      +-- SyntaxError\n",
    "      |    +-- IndentationError\n",
    "      |         +-- TabError\n",
    "      +-- SystemError\n",
    "      +-- TypeError\n",
    "      +-- ValueError\n",
    "      |    +-- UnicodeError\n",
    "      |         +-- UnicodeDecodeError\n",
    "      |         +-- UnicodeEncodeError\n",
    "      |         +-- UnicodeTranslateError\n",
    "      +-- Warning\n",
    "           +-- DeprecationWarning\n",
    "           +-- PendingDeprecationWarning\n",
    "           +-- RuntimeWarning\n",
    "           +-- SyntaxWarning\n",
    "           +-- UserWarning\n",
    "           +-- FutureWarning\n",
    "           +-- ImportWarning\n",
    "           +-- UnicodeWarning\n",
    "           +-- BytesWarning\n",
    "           +-- ResourceWarning\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 Handling Exceptions\n",
    "\n",
    "When <b>an exception is `raised` that causes the program to terminate</b>, \n",
    "\n",
    "**Exceptions, when raised, can and `should be handled` by the program.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numFailures=0 # raise a ZeroDivisionError exception,\n",
    "numSuccesses=1\n",
    "\n",
    "successFailureRatio = numSuccesses/float(numFailures)\n",
    "\n",
    "print('The success/failure ratio is', successFailureRatio)\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "+-- ArithmeticError\n",
    "      |    +-- FloatingPointError\n",
    "      |    +-- OverflowError\n",
    "      |    +-- ZeroDivisionError\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Handle exception:**\n",
    "\n",
    "### 1.1  one kind of exceptions\n",
    "\n",
    "If it is possible for a block of program code to raise \n",
    "```python\n",
    "try:\n",
    "\n",
    "\n",
    "except <type of exceptions>:  \n",
    "\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numFailures=0 # raise a ZeroDivisionError exception,\n",
    "numSuccesses=1\n",
    "\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFailures\n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "    \n",
    "except ZeroDivisionError:\n",
    "    \n",
    "    print('No failures so the success/failure ratio is undefined.')\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### 1.2  more than one kind of exception \n",
    "\n",
    "the reserved word except can be followed by <b>a tuple</b> of exceptions,\n",
    "```python\n",
    "try:\n",
    "\n",
    "\n",
    "except (ArithmeticError, TypeError, NameError):\n",
    "  \n",
    "  \n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numFailures=1\n",
    "numSuccesses=\"11\" # TypeError\n",
    "\n",
    "#successFailureRatio = numSuccesses/numFailures\n",
    "#print('The success/failure ratio is', successFailureRatio)\n",
    "\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFailures\n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "    \n",
    "except (ArithmeticError, TypeError, NameError):\n",
    "    \n",
    "    print('No failures so the success/failure ratio is undefined')\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3  any kind of exception\n",
    "\n",
    "the except block will be entered if <b>any kind of exception </b>is raised within the try  block.\n",
    "\n",
    "```python\n",
    "try:\n",
    "\n",
    "except Exception:\n",
    "\n",
    "\n",
    "```\n",
    "\n",
    "any kind of BaseException\n",
    "\n",
    "```python\n",
    "try:\n",
    "\n",
    "except :\n",
    "\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "numFailures=2 \n",
    "numSuccesses=1\n",
    "\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFail   # raise a NameError exception,\n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "#except Exception:\n",
    "except:\n",
    "    print('No failures so the success/failure ratio is undefined. ')\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### 1.4  Get `information`  of  exception</b>\n",
    "\n",
    "```python\n",
    "try:\n",
    "\n",
    "except <exception> as msg:\n",
    "\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "failures so the success/failure ratio is undefined. \n",
      "\tException information: name 'numFail' is not defined\n",
      "Now here\n"
     ]
    }
   ],
   "source": [
    "numFailures=2 \n",
    "numSuccesses=1\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFail   # raise a NameError exception,\n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "except Exception as msg:\n",
    "    print('failures so the success/failure ratio is undefined. \\n\\tException information:',msg)\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "failures so the success/failure ratio is undefined. \n",
      "\tException information: division by zero\n",
      "Now here\n"
     ]
    }
   ],
   "source": [
    "numFailures=0 # raise a ZeroDivisionError exception,\n",
    "numSuccesses=1\n",
    "\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFailures\n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "    \n",
    "except ZeroDivisionError as msg:\n",
    "    \n",
    "    print('failures so the success/failure ratio is undefined. \\n\\tException information:',msg)\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "failures so the success/failure ratio is undefined. \n",
      "\tException information: unsupported operand type(s) for /: 'int' and 'str'\n",
      "Now here\n"
     ]
    }
   ],
   "source": [
    "numFailures='0' # raise a TypeError exception,\n",
    "numSuccesses=1\n",
    "\n",
    "try:\n",
    "    successFailureRatio = numSuccesses/numFailures\n",
    "    \n",
    "    print('The success/failure ratio is', successFailureRatio)\n",
    "    \n",
    "except (ArithmeticError, TypeError, NameError) as msg:\n",
    "    \n",
    "    print('failures so the success/failure ratio is undefined. \\n\\tException information:',msg)\n",
    "\n",
    "print('Now here')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 Raising Exceptions\n",
    "\n",
    "The <b>raise</b> statement allows the programmer to <b>`force` a `specified` exception</b> to occur. \n",
    "\n",
    "```python\n",
    "raise exceptionName(arguments)\n",
    "```\n",
    "\n",
    "* <b>exceptionName</b>: is usually <b>one of the built-in exceptions</b>\n",
    "\n",
    "\n",
    "* <b>arguments</b> :most of the time the argument is <b>a single string</b>, which is used to <b>describe the reason</b> the exception is being raised.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "raise NameError('force a specified NameError exception')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "raise Exception('force a specified exception')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example,if the passwordat least 6 characters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "password=\"12345\"\n",
    "if (len(password)<6):\n",
    "    raise Exception('password at least 6 characters')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "password=\"12345\"\n",
    "try:\n",
    "    if (len(password)<6):\n",
    "        raise Exception('password at least 6 characters')\n",
    "except Exception as msg:\n",
    "    print(msg)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. User-defined Exceptions\n",
    "\n",
    "Programs may name **their own exceptions** by creating a new exception ```class```\n",
    "\n",
    "Exceptions should typically be derived from the ```Exception``` class, either directly or indirectly. \n",
    "\n",
    "For example:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "code_folding": []
   },
   "outputs": [],
   "source": [
    "class MyException(Exception):\n",
    "    # Whenever a class is instantiated,\n",
    "    # a call is made to the __init__ method defined in that class.\n",
    "    def __init__(self, value):\n",
    "        self.value=value "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    raise MyException(2*2)\n",
    "except  MyException as e:\n",
    "    print('My exception occurred, value:', e.value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  4 Defining Clean-up Actions\n",
    "\n",
    "The <b>try</b> statement has <b>another optional clause</b> \n",
    "\n",
    "```python\n",
    "finally:\n",
    "```\n",
    "\n",
    "which is intended to define <b>clean-up actions</b> that <b>must be executed</b> \n",
    "\n",
    "* under **all circumstances.**\n",
    "\n",
    "* **whether an exception has occurred or not.**\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def divide(x, y):\n",
    "    try:\n",
    "        result = x / y\n",
    "    except ZeroDivisionError:\n",
    "        print(\"division by zero!\")\n",
    "    else:\n",
    "        print(\"result is\", result)\n",
    "    finally:\n",
    "        print(\"executing finally clause\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1 non exception**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "divide(2, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2 an exception has occurred  and handled**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "divide(2, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3 an exception has occurred and not handled**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "divide(\"2\", \"1\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, \n",
    "\n",
    "* the ```finally``` clause is executed in **any event**. \n",
    "\n",
    "\n",
    "* The ```TypeError``` raised by dividing two strings is **not handled** by the except clause and \n",
    "\n",
    "  * therefore <b>re-raised</b> after the ```finally``` clause has been executed.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5 Clean-up Actions\n",
    "\n",
    "In real world applications\n",
    "\n",
    "the ```finally``` clause is useful for <b>releasing external resources - Clean-up Actions</b>\n",
    "\n",
    "such as `files` or `network connections` \n",
    "\n",
    "regardless of whether the use of the resource was successful.\n",
    "\n",
    "Look at the following example, which tries to open a file and print its contents to the screen."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting ./data/myfile.txt\n"
     ]
    }
   ],
   "source": [
    "%%file ./data/myfile.txt\n",
    "1111\n",
    "1111"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1111\n",
      "1111\n"
     ]
    }
   ],
   "source": [
    "f=open(\"./data/myfile.txt\")\n",
    "for line in f:\n",
    "    print(line, end=\"\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "check whether closed f\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check whether closed f\n",
    "f.closed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The <b>problem</b> with this code is that it <b>leaves the file open</b> \n",
    "\n",
    "for an indeterminate amount of time after this part of the code has finished executing.\n",
    "\n",
    "This is not an issue in simple scripts, but can be a problem for larger applications.\n",
    "\n",
    "### 5.1 finally to Clean-up Actions: \n",
    "\n",
    "```python\n",
    "finally:\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1111\n",
      "1111\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    f= open('./data/myfile.txt')\n",
    "   \n",
    "    for line in f:\n",
    "        print(line, end=\"\")\n",
    "\n",
    "finally:\n",
    "    f.close() \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check whether closed f\n",
    "f.closed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.2  Predefined Clean-up Actions\n",
    "\n",
    "Some <b>objects</b> define <b>standard clean-up actions</b> to be undertaken when the object is <b>no longer needed</b>,\n",
    "\n",
    "regardless of whether or not the operation using the object succeeded or failed. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The \n",
    "\n",
    "```python\n",
    "with\n",
    "``` \n",
    "\n",
    "statement allows objects like files to be used in a way that ensures \n",
    "\n",
    "they are always cleaned up promptly and correctly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f=open(\"./data/myfile.txt\")\n",
    "with f:\n",
    "    for line in f:\n",
    "          print(line, end=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# they are always cleaned up promptly and correctly.\n",
    "f.closed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After the statement is executed, the file f is always closed,\n",
    "\n",
    "even if a problem was encountered while processing the lines."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6  The assert statement\n",
    "\n",
    " The Python `assert` statement provides programmers with a simple way to confirm that the state of a computation is as expected.\n",
    " \n",
    " An assert statement can take one of two forms:\n",
    " \n",
    " ```python\n",
    " assert Boolean expression\n",
    " ```   \n",
    " \n",
    "```python\n",
    " assert Boolean expression, argument\n",
    "```\n",
    "\n",
    "\n",
    "When the `assert` statement `fails`, an **AssertionError** is `raised`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The simple form\n",
    "\n",
    "```python\n",
    "assert Boolean expression\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mylist = ['item']\n",
    "assert (len(mylist) >= 1)\n",
    "\n",
    "mylist.pop()\n",
    "assert (len(mylist) >= 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the `assert` statement `fails`, an **AssertionError** is `raised`.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mylist = ['item']\n",
    "assert(len(mylist) >= 1)\n",
    "\n",
    "mylist.pop()\n",
    "try:\n",
    "    assert (len(mylist) >= 1)\n",
    "except AssertionError:\n",
    "    print('AssertionError')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The extended form\n",
    "\n",
    "```python\n",
    "assert Boolean expression1, expression2\n",
    "```\n",
    "expression2 : message\n",
    "\n",
    "```python\n",
    "assert (len(mylist) >= 1),'mylist<1'\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AssertionError mylist<1\n"
     ]
    }
   ],
   "source": [
    "mylist = ['item']\n",
    "assert(len(mylist) >= 1)\n",
    "mylist.pop()\n",
    "try:\n",
    "    assert (len(mylist) >= 1),'mylist<1'\n",
    "except AssertionError as err:\n",
    "    print('AssertionError',err)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using Assertion "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def handlelist(L):\n",
    "    \"\"\" len(mylist) >= 1\"\"\"\n",
    "    assert(len(L) >= 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-5-c2de69adc0c9>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mL\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mhandlelist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mL\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-4-262facc26649>\u001b[0m in \u001b[0;36mhandlelist\u001b[1;34m(L)\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mhandlelist\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mL\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      2\u001b[0m     \u001b[1;34m\"\"\" len(mylist) >= 1\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m     \u001b[1;32massert\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mL\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m: "
     ]
    }
   ],
   "source": [
    "L=[]\n",
    "handlelist(L)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Further Reading\n",
    "\n",
    "Python3 Tutorial: 8. Errors and Exceptions\n",
    "\n",
    "* https://docs.python.org/3/tutorial/errors.html#exceptions\n",
    " \n",
    "\n",
    "Python3 Refernce 7.3 : The ```assert``` statement  \n",
    "\n",
    "* https://docs.python.org/3/reference/simple_stmts.html#assert\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "278.25px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
